﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Dubbo.Rpc
{
    public abstract class AbstractProxyInvoker<T> : IInvoker<T>
    {
        private readonly T proxy;
        
        public AbstractProxyInvoker(T proxy, URL url)
        {
            if (proxy == null)
            {
                throw new ArgumentException("proxy == null");
            }
            this.proxy = proxy;
            this.Url = url;
        }

        public URL Url { get; private set; }

        public bool IsAvailable { get { return true; } }

        public void Destroy()
        {
        }

        public IResult Invoke(IInvocation<T> invocation)
        {
            try
            {
                return new RpcResult(DoInvoke(proxy, invocation.MethodName, invocation.ParameterTypes, invocation.Arguments));
            }
            //catch (InvocationTargetException e)
            //{
            //    return new RpcResult(e.getTargetException());
            //}
            catch (Exception e)
            {
                throw new RpcException("Failed to invoke remote proxy method " + invocation.MethodName + " to " + Url + ", cause: " + e.Message, e);
            }
        }

        protected abstract object DoInvoke(T proxy, string methodName, Type[] parameterTypes, object[] arguments);

        public override string ToString()
        {
            return typeof(T) + " -> " + Url == null ? " " : Url.ToString();
        }
    }
}
